package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.dao.bean.User;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.play.TableUtil;
import com.jule.teenpatti.log.service.LogReasons;
import com.jule.teenpatti.game.dao.DBUtil;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_ApplyBuyInAck_50004;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.service.MoneyService;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 申请买入筹码
 */
public class JoloGame_ApplyBuyInReq_50004 extends ClientReq {
    private long time;
    private final static Logger logger = LoggerFactory.getLogger(JoloGame_ApplyBuyInReq_50004.class);

    public JoloGame_ApplyBuyInReq_50004(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_ApplyBuyInReq req;

    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_ApplyBuyInReq.parseFrom(blob);
        this.setTable(TableService.getInstance().getTable(header.gameId + "", req.getRoomId(), req.getTableId()));
    }

    @Override
    public void processImpl() throws Exception {
        logger.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "req->" + req.toString());
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        double buyInScore = 0;

        AbstractTable table = getTable();
        PlayerInfo player = table.getPlayer(userId);
        JoloGame.JoloGame_ApplyBuyInAck.Builder ack = JoloGame.JoloGame_ApplyBuyInAck.newBuilder();
        try {
            ack.setUserId(userId);
            ack.setRoomId(roomId);
            ack.setTableId(tableId);

            User user = DBUtil.selectByPrimaryKey(userId);
            if (null == player || null == user) {
                logger.info("can't found player info, playerId->" + userId);
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50050_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyBuyInAck_50004(ack.build(), header));
                return;
            }

            if (player.getSeatNum() <= 0) {
                logger.info("玩家无座位，不能买入, playerId->" + userId);
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50014_1.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyBuyInAck_50004(ack.build(), header));
                return;
            }

            //赋值buyInScore，如果没有指定buyInScore，那么全额库存代入
            if (req.hasBuyInScore()) {
                buyInScore = req.getBuyInScore();
            } else {
                buyInScore = user.getMoney();
            }

            double playScoreStore = player.getPlayScoreStore();//玩家牌桌上积分的携带量

            double curentMoney = MoneyService.getInstance().buyScore(player.getPlayerId(), buyInScore);
            if (curentMoney < 0) {
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50001_4.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyBuyInAck_50004(ack.build(), header));
                return;
            }
            player.setTotalTakeInScore(player.getTotalTakeInScore() + buyInScore);
            ack.setResult(1);
            ack.setCurrPlayScore(playScoreStore + buyInScore); //TODO：如果玩家正在牌局进行状态中，那么需要等本局结算后再进行最新总代入库存的增加操作（为了避免出现刷币漏洞，如：玩家在买入时，playScoreStore发生了变化）
            ack.setCurrStoreScore(curentMoney);
            ctx.writeAndFlush(new JoloGame_ApplyBuyInAck_50004(ack.build(), header));

            //player.setPlayScoreStore(playScoreStore + buyInScore);
            player.addPlayScoreStore(buyInScore, LogReasons.CommonLogReason.GAME_BUY_IN);
            //发送通知
            NoticeBroadcastMessages.moneyChangeNotice(table,userId,player.getPlayScoreStore());
            try {
                //广播玩家买入筹码
                NoticeBroadcastMessages.buyIn(table, userId, buyInScore);
            } catch (Exception ex) {
                logger.error("Send Notice ERROR", ex);
            }
            long timeMillis = System.currentTimeMillis() - time;
            if (timeMillis > GameConst.COST_TIME) {
                LoggerUtils.performance.info("ApplyBuyInReq_50004,cost time:{},req:{}", timeMillis, req.toString());
            }
        } catch (Exception ex) {
            ack.setResult(-10).setResultMsg(ErrorCodeEnum.GAME_50002_2.getCode());
            ctx.writeAndFlush(new JoloGame_ApplyBuyInAck_50004(ack.build(), header));
            logger.error("", ex);
        } finally {
            if (null != table) {
                logger.debug("All Player info: " + System.getProperty("line.separator") + TableUtil.toStringAllPlayers(table));

                logger.debug("InGame Player info: " + System.getProperty("line.separator") + TableUtil.toStringInGamePlayers(table));
            }
            logger.debug("BuyIn over. Table state: " + table.getTableStateEnum());
        }
    }
}
